package com.example.gateway.service.impl;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.GifCaptcha;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.captcha.generator.MathGenerator;
import cn.hutool.captcha.generator.RandomGenerator;
import cn.hutool.core.util.StrUtil;
import com.example.commons.core.constant.CacheConstants;
import com.example.commons.core.constant.Constants;
import com.example.commons.core.exception.CaptchaException;
import com.example.commons.core.web.AjaxResult;
import com.example.gateway.config.properties.CaptchaProperties;
import com.example.gateway.service.ValidateCodeService;
import com.example.hsgredis.service.RedisService;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * 验证码实现处理
 *
 */
@Service
public class ValidateCodeServiceImpl implements ValidateCodeService {

    private final RedisService redisService;

    private final CaptchaProperties captchaProperties;

    public ValidateCodeServiceImpl(RedisService redisService, CaptchaProperties captchaProperties) {
        this.redisService = redisService;
        this.captchaProperties = captchaProperties;
    }

    /**
     * 生成验证码
     */
    @Override
    public AjaxResult createCaptcha() throws IOException, CaptchaException {
        AjaxResult ajax = AjaxResult.success();
        boolean captchaEnabled = captchaProperties.getEnabled();
        ajax.put("captchaEnabled", captchaEnabled);
        if (!captchaEnabled) {
            return ajax;
        }

        // 保存验证码信息
        String uuid = StrUtil.uuid();
        String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid;

        String capStr = null, code = null;
        String imageBase64 = null;

        String captchaType = captchaProperties.getType();
        // 生成验证码

        if ("num".equals(captchaType)) {
            LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(133, 45);
            RandomGenerator randomGenerator = new RandomGenerator("0123456789", 4);
            lineCaptcha.setGenerator(randomGenerator);
            code = lineCaptcha.getCode();
            imageBase64 = lineCaptcha.getImageBase64();
        } else if ("math".equals(captchaType)) {
            GifCaptcha captcha = CaptchaUtil.createGifCaptcha(133, 45);
            // 自定义验证码内容为四则运算方式
            captcha.setGenerator(new MathGenerator());
            code = captcha.getCode();
            imageBase64 = captcha.getImageBase64();
        }

        redisService.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
        ajax.put("uuid", uuid);
        ajax.put("img", imageBase64);
        return ajax;
    }

    /**
     * 校验验证码
     */
    @Override
    public void checkCaptcha(String userInputCode, String uuid) throws CaptchaException {
        if (StrUtil.isEmpty(userInputCode)) {
            throw new CaptchaException("验证码不能为空");
        }
        if (StrUtil.isEmpty(uuid)) {
            throw new CaptchaException("验证码已失效");
        }
        String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid;
        String code = redisService.getCacheObject(verifyKey);
        String captchaType = captchaProperties.getType();
        if ("math".equals(captchaType)) {
            MathGenerator m = new MathGenerator();
            Assert.isTrue(m.verify(code,userInputCode),"验证码错误，请重新输入");
        } else if ("num".equals(captchaType)) {
            Assert.isTrue(userInputCode.equals(code),"验证码错误，请重新输入");
        }
        redisService.deleteObject(verifyKey);

    }
}
